package com.hw.saweb.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @program: sa-token-start
 * @author: hewei
 * @date: 2023-09-06 15:51
 * <p>
 * 在 Sa-Token 中，Session 分为三种，分别是：
 * <p>
 * Account-Session: 指的是框架为每个 账号id 分配的 Session
 * Token-Session: 指的是框架为每个 token 分配的 Session
 * Custom-Session: 指的是以一个 特定的值 作为SessionId，来分配的 Session
 * HttpSession并未被框架接管，在使用Sa-Token时，请在任何情况下均使用SaSession，不要使用HttpSession
 **/

@Slf4j
@RestController
@RequestMapping("/session")
public class SessionController {

    @RequestMapping("/accountSession")
    public String accountSession() {
        // 获取当前账号 id 的 Account-Session (必须是登录后才能调用)
        SaSession session=StpUtil.getSession();
        session.set("account","sa");
        session.set("password","123456");
        session.keys().stream().forEach(k->log.info("Session properties：{} - {}",k,session.get(k).toString()));

        // 获取当前登录账号的 LoginId ，也就是 Constant.USER_ID
//        StpUtil.getLoginId();
        // 返回当前token的登录设备类型
//        StpUtil.getLoginDevice();
        // 获取当前账号的 token
//        SaTokenInfo token=StpUtil.getTokenInfo();
        // 获取指定loginId指定设备类型端的tokenValue
//        StpUtil.getTokenValueByLoginId(Constant.USER_ID, "APP");
        // 获取当前账号 id 的 Account-Session, 并决定在 Session 尚未创建时，是否新建并返回
//        StpUtil.getSession(true);

        // 获取账号 id 为 10000 的 Account-Session，可以用来获取其他用户session
//        StpUtil.getSessionByLoginId(10000);

        // 获取账号 id 为 10000 的 Account-Session, 并决定在 Session 尚未创建时，是否新建并返回
//        StpUtil.getSessionByLoginId(10000, true);

        // 获取 SessionId 为 xxxx-xxxx 的 Account-Session, 在 Session 尚未创建时, 返回 null
//        StpUtil.getSessionBySessionId("xxxx-xxxx");

        // 返回此 Session 的id
//        session.getId();

        // 返回此 Session 的创建时间 (时间戳)
//        session.getCreateTime();

        // 返回此 Session 会话上的底层数据对象（如果更新map里的值，请调用session.update()方法避免产生脏数据）
//        session.getDataMap();

        // 将这个 Session 从持久库更新一下
//        session.update();

        // 注销此 Session 会话 (从持久库删除此Session)
//        session.logout();


        return session.getId();
    }

    @RequestMapping("/tokenSession")
    public String tokenSession() {

        // 获取当前 Token 的 Token-Session 对象
        SaSession session=StpUtil.getTokenSession();

        // 获取指定 Token 的 Token-Session 对象
//        StpUtil.getTokenSessionByToken(token);

        return session.getId();
    }

    /**
     * 自定义 Session 指的是以一个特定的值作为 SessionId 来分配的Session, 借助自定义Session，你可以为系统中的任意元素分配相应的session
     * 例如以商品 id 作为 key 为每个商品分配一个Session，以便于缓存和商品相关的数据
     * */
    @RequestMapping("/customSession")
    public String customSession() {

        // 查询指定key的Session是否存在
//        SaSessionCustomUtil.isExists("goods-10001");

        // 获取指定key的Session，如果没有，则新建并返回
        SaSession session=SaSessionCustomUtil.getSessionById("goods-10001");

        // 获取指定key的Session，如果没有，第二个参数决定是否新建并返回
//        SaSessionCustomUtil.getSessionById("goods-10001", false);

        // 删除指定key的Session
//        SaSessionCustomUtil.deleteSessionById("goods-10001");


        return session.getId();
    }

    @SaIgnore
    @RequestMapping("/anonSession")
    public String anonSession(){
        // 获取当前 Token 的匿名 Token-Session （可在未登录情况下使用的 Token-Session）
        SaSession session=StpUtil.getAnonTokenSession();
        return session.getId();
    }

    @RequestMapping("/switchID")
    public String switchID(String id){
//        log.info("身份切换开始！");
        // 将当前会话[身份临时切换]为其它账号（本次请求内有效），
        // 如果在switchTo中使用了Lambda 表达式，则Lambda 表达式执行完之后身份会恢复到当前
//        StpUtil.switchTo(id,()->{
//            log.info("当前身份临时切换：{} 此时用户账号ID:{}",StpUtil.isSwitch(),StpUtil.getLoginId());
//        });
//        log.info("身份切换结束！");

        log.info("身份切换开始！");
        StpUtil.switchTo(id);
        log.info("当前身份临时切换：{} ，此时用户账号ID:{}",StpUtil.isSwitch(),StpUtil.getLoginId());
        // 此时再调用此方法会返回 参数id (我们临时切换到的账号id)
        String loginID= (String) StpUtil.getLoginId();
        // 结束 [身份临时切换]
        StpUtil.endSwitch();
        log.info("身份切换结束后的ID：{}",StpUtil.getLoginId());
        return "身份切换后的ID："+loginID;
    }
}
